<?php

namespace App\Http\Controllers;

use App\Models\ProxyBatch;
use App\Models\ProxyDetail;
use App\Models\ProxyUser;
use App\Models\Region;
use App\Models\StaticProxyDetail;
use App\Models\User;
use App\Services\ProxyService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ProxyController extends Controller
{
    protected $proxyService;

    public function __construct(ProxyService $proxyService)
    {
        $this->proxyService = $proxyService;
    }

    /**
     * 动态代理记录
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function dynamic(Request $request)
    {
        $user_id = Auth::id();
        // 管理员帐户处理
        if ($user_id == 100000) {
            $user_id = 100001;
        }
        $limit = $request->input('limit', 5);
        $page = $request->input('page', 1);
        $offset = ($page - 1) * $limit;

        $query = ProxyBatch::where('user_id', $user_id);
        $count = $query->count();
        $list = $query->offset($offset)->limit($limit)->orderBy('id', 'desc')->get();
        foreach ($list as $row) {
            $row->created_time = $row->created_at->format('Y-m-d H:i:s');
            if (App::getLocale() == 'en') {
                $row->country = $row->country . '-' . $row->country_code;
            } else {
                $row->country = $row->country_alias . '-' . $row->country_code;
            }
            $row->region = $row->region . '-' . $row->city;
            unset($row->created_at, $row->updated_at);
        }
        return response()->json([
            'errcode' => 0,
            'errmsg' => __('common.success'),
            'data' => [
                'count' => $count,
                'list' => $list
            ]
        ]);
    }

    /**
     * 创建动态代理
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function createDynamic(Request $request)
    {
        $user_id = Auth::id();
        $country_code = $request->input('country');
        $region_code = $request->input('region', '');
        $city_code = $request->input('city', '');
        $node = $request->input('node');
        $time = $request->input('time');
        $quantity = $request->input('quantity');
        $password = $request->input('password');
        $password = trim($password);

        DB::beginTransaction();
        try {
            // 管理员帐户处理
            if ($user_id == 100000) {
                $user_id = 100001;
            }
            $user = User::find($user_id);
            if (floatval($user->traffic) <= 0) {
                throw new Exception(__('common.recharge_reminder'), 1);
            }
            $proxyUser = ProxyUser::where('user_id', $user_id)->where('status', 1)->first();
            if (empty($proxyUser)) {
                throw new Exception(__('common.failure'), 1);
            }
            // 更新代理账号密码
            $this->proxyService->updateProxyUser($user_id, $password);

            $country_info = Region::select('country', 'country_alias')->where('country_code', $country_code)->first();
            if (empty($country_info)) {
                throw new Exception(__('common.failure'), 1);
            }
            if (!empty($region_code)) {
                $region = Region::where('region_code', $region_code)->value('region');
            }
            if (!empty($city_code)) {
                $city = Region::where('city_code', $city_code)->value('city');
            }
            $batch_data = [
                'user_id' => $user_id,
                'proxy_username' => $proxyUser->username,
                'country' => $country_info->country,
                'country_alias' => $country_info->country_alias,
                'country_code' => $country_code ?? '',
                'region' => $region ?? '',
                'region_code' => $region_code ?? 0,
                'city' => $city ?? '',
                'city_code' => $city_code ?? 0,
                'node' => $node,
                'time' => $time,
                'quantity' => $quantity
            ];
            $proxyBatch = ProxyBatch::create($batch_data);
            if (empty($proxyBatch)) {
                throw new Exception(__('common.failure'), 2);
            }
            $proxys = $this->proxyService->createProxy($user_id, $quantity, $time, $country_code, $region_code, $city_code);
            $proxy_detail = [];
            foreach ($proxys as $proxy) {
                $proxy_detail[] = [
                    'batch_id' => $proxyBatch->id,
                    'proxy' => $proxy,
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            $proxyDetail = ProxyDetail::insert($proxy_detail);
            if (empty($proxyDetail)) {
                throw new Exception(__('common.failure'), 3);
            }
            DB::commit();
            return response()->json([
                'errcode' => 0,
                'errmsg' => __('common.success')
            ]);
        } catch (Exception $e) {
            Log::info('message：' . $e->getMessage() . ' line：' . $e->getLine() . ' file：');
            DB::rollBack();
            return response()->json([
                'errcode' => -1,
                'errmsg' => $e->getMessage()
            ]);
        }
    }

    public function exportDynamic(Request $request)
    {
        $batch_id = $request->input('batch_id');
        if (empty($batch_id)) {
            return response()->json([
                'errcode' => -1,
                'errmsg' => __('common.failure')
            ]);
        }
        try {
            $batch_info = ProxyBatch::find($batch_id);
            $proxy_pwd = ProxyUser::where('user_id', $batch_info['user_id'])->value('pwd');
            $data = [];
            $proxys = ProxyDetail::select('proxy')->where('batch_id', $batch_id)->pluck('proxy');
            foreach ($proxys as $proxy) {
                $data[] = $batch_info['node'] . ':7778:' . $proxy . ':' . Crypt::decryptString($proxy_pwd);
            }
            $content = implode("\n", $data);
            $filename = date('YmdHis') . '_proxy.txt';
            return response()->streamDownload(function () use ($content) {
                echo $content;
            }, $filename);
        } catch (Exception $e) {
            Log::error('导出代理失败：batch_id -> ' . $batch_id . '，异常消息：' . $e->getMessage());
            return '';
        }
    }

    public function destroyDynamic(Request $request)
    {
        $batch_id = $request->input('batch_id');
        $proxyBatch = ProxyBatch::find($batch_id);
        if (!empty($proxyBatch)) {
            $proxyBatch->delete();
            ProxyDetail::where('batch_id', $batch_id)->delete();
            return response()->json([
                'errcode' => 0,
                'errmsg' => __('common.success')
            ]);
        }
        return response()->json([
            'errcode' => -1,
            'errmsg' => __('common.failure')
        ]);
    }

    /**
     * 静态代理记录
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function static(Request $request)
    {
        $user_id = Auth::id();
        // 管理员帐户处理
        if ($user_id == 100000) {
            $user_id = 100001;
        }
        $country_code = $request->input('country_code', '');
        $business = $request->input('business', '');
        $status = $request->input('status', '');
        $limit = $request->input('limit', 5);
        $page = $request->input('page', 1);
        $offset = ($page - 1) * $limit;

        $field = ['order_nu', 'sort', 'country_code', 'business', 'line_type', 'status', 'created_at', 'expired_time', 'ip', 'port', 'account', 'password'];
        $query = StaticProxyDetail::select($field)->where('user_id', $user_id);
        if (!empty($country_code)) {
            $query = $query->where('country_code', $country_code);
        }
        if (!empty($business)) {
            $query = $query->where('business', $business);
        }
        if (is_numeric($status) && in_array($status, [0, 1, 2])) {
            if ($status == 1) {
                $query = $query->whereIn('status', [1, 2]);
            } else {
                $query = $query->where('status', $status);
            }
        }
        $count = $query->count();
        $list = $query->offset($offset)->limit($limit)->orderBy('id', 'desc')->orderBy('sort')->get();
        foreach ($list as $row) {
            $row->created_time = $row->created_at->format('Y-m-d H:i:s');
            unset($row->created_at);
            $row->proxy_info = $row->ip . ':' . $row->port . ':' . $row->account. ':' . $row->password;
        }
        return response()->json([
            'errcode' => 0,
            'errmsg' => __('common.success'),
            'data' => [
                'count' => $count,
                'list' => $list
            ]
        ]);
    }
}
